package cz.cuni.amis.episodic.lisp.netcreators;

import java.util.List;
import java.util.Set;

import cz.cuni.amis.episodic.lisp.LispPlanToCsvData;
import cz.cuni.amis.episodic.lisp.LispPlanToCsvData.BehanFilteredProcessor;
import smile.Network;

/**
 * CHMM as specified by Blaylock and Allen 2005.
 *
 * @author ik
 */
public class CHMMCreator extends NetCreator {

    boolean observationTemporalModel;
    
    public CHMMCreator(boolean observationTemporalModel) {
        filenameSuffix = "_chmm";
        this.observationTemporalModel = observationTemporalModel;
    }

    public CHMMCreator(boolean observationTemporalModel, int levels) {
        this(observationTemporalModel);
		String observ = observationTemporalModel ? "-obs" : "";
		filenameSuffix += observ + "^" + levels;
        translator = new  LispPlanToCsvData.BehanFilteredProcessor(levels+1);
    } 
    
    public CHMMCreator(boolean observationTemporalModel, TraceModificationStrategy strategy) {
        this(observationTemporalModel);
        String observ = observationTemporalModel ? "-obs" : "";
        filenameSuffix += observ + "^" + strategy.getDepth();
        setTraceModificationStrategy(strategy);
    } 
    
    @Override
    public Network createNet(List<List<String>> levelActions) {
        final int max = levelActions.size();

        // create network
        Network net = new Network();
        String[] nodes = new String[max];
        for (int i = 0; i < max - 1; i++) {
            int id = max - i - 1;
            nodes[i] = "G" + id;
            // G
            addNode(net, nodes[i], levelActions.get(i));
            if (i > 0) { // G_(i-1) -> G_i
                net.addArc(nodes[i - 1], nodes[i]);
            }
        }
        nodes[max - 1] = "O";
        // observation O
        addNode(net, nodes[max - 1], levelActions.get(levelActions.size() - 1));
        // G_last -> O
        net.addArc(nodes[max - 2], nodes[max - 1]);

        // add temporal arcs
        adjustNodes(net, nodes, observationTemporalModel);
        return net;
    }
}
